package com.gitee.qdbp.general.common.biz.sequence.service;

import java.util.Date;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.general.common.api.sequence.service.ILocalSequenceGenerator;
import com.gitee.qdbp.tools.utils.DateTools;
import com.gitee.qdbp.tools.utils.RandomTools;
import com.gitee.qdbp.tools.utils.VerifyTools;

/**
 * 本地序列号生成器(时间+随机数)<br>
 * 15位时间(年月日时分秒毫秒)+主机编号+10位随机数<br>
 * 主机编号可为空, 因为同一秒内10位随机数产生碰撞的概率可以忽略不计<br>
 * 之前12位时间+8位随机数, 冲突的概率很大!
 *
 * @author zhaohuihua
 * @version 170722
 */
// @Service
public class TimeRandomSequenceGenerator implements ILocalSequenceGenerator {

    /** 本机的主机编号 **/
    private String hostCode;

    /** 默认的序号位数 **/
    private int digitNumber = 10;

    /** 时间部分的格式 **/
    private String timeFormat = "yyMMddHHmmssSSS";

    /**
     * 生成一个新的序号
     * 
     * @param type 类型
     * @param subtypes 子类型
     * @return 序号
     * @throws ServiceException
     */
    @Override
    public String generate(String type, String... subtypes) throws ServiceException {
        String currTime = getCurrTime(timeFormat);
        String currValue = RandomTools.generateNumber(digitNumber);
        String hostCode = VerifyTools.isBlank(this.hostCode) ? "" : this.hostCode;
        return currTime + hostCode + currValue;
    }

    // 获取当前时间作为序号的前缀
    private static String getCurrTime(String timeFormat) {
        return DateTools.format(new Date(), timeFormat);
    }

    /** 本机的主机编号(可为空) **/
    public String getHostCode() {
        return hostCode;
    }

    /** 本机的主机编号(可为空) **/
    public void setHostCode(String hostCode) {
        this.hostCode = hostCode;
    }

    /** 默认的序号位数 **/
    public int getDigitNumber() {
        return digitNumber;
    }

    /** 默认的序号位数 **/
    public void setDigitNumber(int digitNumber) {
        this.digitNumber = digitNumber;
    }

    /** 默认的时间部分的格式 **/
    public String getTimeFormat() {
        return timeFormat;
    }

    /** 默认的时间部分的格式 **/
    public void setTimeFormat(String timeFormat) {
        this.timeFormat = timeFormat;
    }

}
